package it.tcon.xbeedriver.resmanager;

import org.apache.log4j.Logger;

import it.tcon.xbeedriver.XBeeNode;
import it.tcon.xbeedriver.XBeeNodeException;
import it.tcon.xbeedriver.XBeeNodeList;

import com.rapplogic.xbee.api.AtCommandResponse;
import com.rapplogic.xbee.api.zigbee.NodeDiscover;
import com.rapplogic.xbee.util.ByteUtils;

/**
 * XBee AT Response Manager:
 * <br /> Manager for all the AT command response received by this device.
 * All this AT command came from this device, 
 * so the address of the transmitter the same of this device.
 * @author Alyver00
 *
 */
public class AtResponseManager {

	//private AtCommandResponse response;
	private String command;
	private int[] value;
	private XBeeNode coordinator;
	private XBeeNodeList list;
	
	private Logger logger = Logger.getLogger(AtResponseManager.class);
	
	public AtResponseManager(AtCommandResponse response,XBeeNodeList list){
		//this.response = response;
		this.command = response.getCommand();
		this.value = response.getValue();
		this.coordinator = list.getCoordinatorNode();
		this.list = list;
		
		responseCommandCheck(response);
		logger.debug("Message Checked by AtResponseManager");
	}
	
	/**
	 * Check the type of command received and run the correct method
	 * @param response The response from the XBeeReceiveController.
	 */
	//TODO a better check without if
	public void responseCommandCheck(AtCommandResponse response){
		
		
		
		if(command.compareTo("DH") == 0){
			logger.debug("Response of an DH command");
			this.coordinator.setDestinationAddrHigh(value);
			this.list.updateNode(this.coordinator);
		}	
		else if(command.compareTo("DL") == 0){
			logger.debug("Response of an DL command");
			this.coordinator.setDestinationAddrLow(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("MY") == 0){
			logger.debug("Response of an MY command");
			this.coordinator.setMy16BitAddress(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("MP") == 0){
			/*logger.debug("Response of an MY command");
			this.coordinator.setMy16BitAddress(value);
			this.list.updateNode(this.coordinator);*/
		}
		else if(command.compareTo("SH") == 0){
			logger.debug("Response of an SH command");
			this.coordinator.setSerialNumberHigh(value);
			this.list.updateNode(this.coordinator);
			
		}
		else if(command.compareTo("SL") == 0){
			logger.debug("Response of an SL command");
			this.coordinator.setSerialNumberLow(value);
			this.list.updateNode(this.coordinator);
			
		}
		else if(command.compareTo("NI") == 0){
			logger.debug("Response of an NI command");
			this.coordinator.setNodeIdentifier(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("DD") == 0){
			logger.debug("Response of an DD command");
			this.coordinator.setDeviceTypeIdentifier(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("ZA") == 0){
			//TODO ZigBee Application Layer
		}
		else if(command.compareTo("SE") == 0){
			//TODO Source Endpoint
		}
		else if(command.compareTo("DE") == 0){
			//TODO Destination Endpoint
		}
		else if(command.compareTo("CI") == 0){
			//TODO Cluster Identifier
		}
		else if(command.compareTo("BI") == 0){
			//TODO Binding table index
		}
		else if(command.compareTo("CH") == 0){
			logger.debug("Response of an CH command");
			this.coordinator.setOperatingChannel(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("ID") == 0){
			logger.debug("Response of an ID command");
			this.coordinator.setPANID(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("BH") == 0){
			logger.debug("Response of an BH command");
			this.coordinator.setBroadcastRadius(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("ND") == 0){
			NodeDiscover discoverNode = null;
			discoverNode = NodeDiscover.parse(response);
			
			if(discoverNode != null){
				logger.debug("ND Device Address: "+ByteUtils.toBase16(discoverNode.getNodeAddress64().getAddress()));
				logger.debug("ND Device type: "+discoverNode.getDeviceType());
				XBeeNode newNode = new XBeeNode(discoverNode.getNodeAddress64(),discoverNode.getDeviceType());
				String address = ByteUtils.toBase16(discoverNode.getNodeAddress64().getAddress());
				newNode.setActive(true);
				try {
					this.list.addNode(newNode);
				} catch (XBeeNodeException e) {
						if(e.getMessage().compareTo("NodeAlreadyOnListException") == 0){
							XBeeNode node = this.list.getNode(address);
							node.setActive(true);
							this.list.updateNode(node);
							logger.error("Error adding an XBee module: node already on the list");
						}
						else if(e.getMessage().compareTo("XBeeNodeAddressNotFoundException") == 0)
							logger.error("Error adding an XBee module: node address not found");
					//e.printStackTrace();
				}
				logger.debug("Added a XBee Module");

				//System.out.println("Module added");
				//if(addDiscoverDevice(newNode)){
				//	System.out.println("Device added");
				//}
			}
			
		}
		else if(command.compareTo("DN") == 0){
			//TODO Destination node
		}
		else if(command.compareTo("JN") == 0){
			//TODO Join notification
		}
		else if(command.compareTo("SC") == 0){
			logger.debug("Response of an SC command");
			this.coordinator.setScanChannels(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("SD") == 0){
			logger.debug("Response of an SD command");
			this.coordinator.setScanDuration(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("NJ") == 0){
			logger.debug("Response of an NJ command");
			this.coordinator.setNodeJoinDuration(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("AR") == 0){
			logger.debug("Response of an AR command");
			this.coordinator.setAggregationRouteBCTime(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("AI") == 0){
			//TODO association indication
		}
		else if(command.compareTo("PL") == 0){ // Power Level
			this.coordinator.setPowerLevel(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("PM") == 0){ // Power Mode
			logger.debug("Response of an PM command");
			this.coordinator.setPowerMode(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("AP") == 0){
			logger.debug("Response of an AP command");
			this.coordinator.setAPIEnable(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("AO") == 0){
			logger.debug("Response of an AO command");
			this.coordinator.setAPIOptions(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("BD") == 0){
			logger.debug("Response of an BD command");
			this.coordinator.setBaudRate(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("VR") == 0){
			logger.debug("Response of an VR command");
			this.coordinator.setFirmwareVersion(value);
			this.list.updateNode(this.coordinator);
		}
		else if(command.compareTo("HV") == 0){
			logger.debug("Response of an HV command");
			this.coordinator.setHardwareVersion(value);
			this.list.updateNode(this.coordinator);
		}
		
	}
	
	
	
	
	
}
